﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Rhino.Mocks;

namespace T4EditorClassifier.Tests.Tag
{
    /// <summary>
    /// http://vscoloroutput.codeplex.com/SourceControl/changeset/view/9f1008bf223b#Tests%2fOutputClassifierTests.cs
    /// http://vscoloroutput.codeplex.com/SourceControl/changeset/view/9f1008bf223b#VSColorOutput%2fOutputClassifier.cs
    /// </summary>
    [TestClass]
    public partial class T4TagClassifierTests
    {
        [TestMethod]
        public void FindMatchingOpenChar_NoMatchMultiline()
        {
            
            var s=ClassificationTestHelper.SetupSnapshot(" \r\n#>");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsFalse(found);

        }



        [TestMethod]
        public void FindMatchingOpenCharNoMatch()
        {

            var s = ClassificationTestHelper.SetupSnapshot(" #>  ");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsFalse(found);

        }

        [TestMethod]
        public void FindMatchingOpenChar_Match()
        {

            var s = ClassificationTestHelper.SetupSnapshot(" <#  #>  ");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsTrue(found);

        }

        [TestMethod]
        public void FindMatchingOpenChar_CloseAsFirstItemOfNewLine_Match()
        {

            var s = ClassificationTestHelper.SetupSnapshot(" <#  \r\n#>  ");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsTrue(found);

        }

        [TestMethod]
        public void FindMatchingOpenChar_MatchMultiLine()
        {

            var s = ClassificationTestHelper.SetupSnapshot(" <# \r\n #>  ");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsTrue(found);

        }

        [TestMethod]
        public void FindMatchingOpenChar_MatchMultiLineNonMatchLineInMiddle()
        {

            var s = ClassificationTestHelper.SetupSnapshot(" <# \r\n empty line \r\n #>  ");
            var c = ClassificationTestHelper.SetupClassifier(GetClassifier);
            var sp = new SnapshotPoint(s, s.GetText().IndexOf("#>"));
            SnapshotSpan pairSpan;
            var found = T4TagClassifier.FindMatchingOpenChar(sp, c, "<#", "#>", 2, out pairSpan);
            Assert.IsTrue(found);

        }

        [TestMethod]
        public void GetClassificationSpans_NoMatch()
        {
            var source = "/ /";

            var actual = GetClassificationSpans(source);

            Assert.IsTrue(actual.Count == 0);

        }
      
       

        [TestMethod]
        public void GetClassificationSpans_OpenCloseTag_ReturnsBoth()
        {
            var source="<# #>";


            var actual = GetClassificationSpans(source);

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Any());
            Assert.IsTrue(actual.Count == 2);

        }

        [TestMethod]
        public void GetClassificationSpans_OpenCloseExpressionTag_ReturnsBoth()
        {
            var source = "<#= #>";

            var actual = GetClassificationSpans(source);

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Any());
            Assert.IsTrue(actual.Count == 2);
            Assert.AreEqual("<#=", actual[0].Span.GetText());
            Assert.AreEqual("#>", actual[1].Span.GetText());

        }

        [TestMethod]
        public void GetClassificationSpans_OpenExpressionTag_OpenLengthIs3()
        {
            var source = "<#=";

            var actual = GetClassificationSpans(source);
            Assert.IsTrue(actual.Count == 1);
            Assert.AreEqual(source, actual.First().Span.GetText());
          
        }

        [TestMethod]
        public void GetClassificationSpans_OpenExpressionTagAfterLt_OpenLengthIs3()
        {
            var source = "<<#=";

            var actual = GetClassificationSpans(source);
            Assert.IsTrue(actual.Count == 1);
            var txt = actual.First().Span.GetText();

            Assert.AreEqual("<#=", txt);
        }

        [TestMethod]
        public void GetClassificationSpans_SpaceOpenExpressionTagAfterLtSpace_OpenLengthIs3()
        {
            var source = " <<#= ";

            var actual = GetClassificationSpans(source);
            Assert.IsTrue(actual.Count == 1);
            var txt=actual.First().Span.GetText();
            Assert.AreEqual("<#=", txt);
            
        }

        [TestMethod]
        public void GetClassificationSpans_OpenDirectiveTag_ReturnsBoth()
        {
            var source = "<#@";

            var actual = GetClassificationSpans(source);
            Assert.IsTrue(actual.Count == 1);
            Assert.AreEqual(source, actual.First().Span.GetText());


        }

        [TestMethod]
        public void GetClassificationSpans_OpenFeatureBlockTag_ReturnsBoth()
        {
            var source = "<#+";

            var actual = GetClassificationSpans(source);

            Assert.IsTrue(actual.Count == 1);
            Assert.IsTrue(actual.First().Span.GetText().Length == 3);

        }

        [TestMethod]
        public void GetClassificationSpans_OpenCloseTagDifferentLines_ReturnsBoth()
        {
            var source = "<# \r\n #>";

            var actual = GetClassificationSpans(source);

            Assert.IsTrue(actual.Count == 2);
            Assert.AreEqual("<#", actual.First().Span.GetText());
            Assert.AreEqual("#>", actual[1].Span.GetText());

        }

      

    }
}
